package com.link.base.base.common.controller;

import com.link.base.base.common.model.Attachment;
import com.link.base.base.common.service.AttachmentService;
import com.link.base.user.model.CoreUser;
import com.link.core.basic.model.ReturnCodeConstants;
import com.link.core.basic.model.UploadImgInfo;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.cllog.LCLogger;
import com.link.core.basic.annotations.JsonParam;
import com.link.core.basic.controller.BasicController;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.service.BasicService;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.basic.service.ServiceException;
import com.link.core.modules.export.ExportFactory;
import com.link.core.modules.export.ExportWriter;
import com.link.core.util.*;
import com.link.base.core.basic.util.YmlConstants;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * Copyright  hande Company. All Rights Reserved.
 *
 * @author  unknwon
 * @date:   2018/11/8 19:07
 * @version 1.0
 */

@Controller
@RequestMapping("/link/attachment")
public class AttachmentController extends BasicController<Attachment> {

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private KeyGenerateService keyGenerateService;

    /**
     * 模拟登陆用户名 redis key
     */
    private static final String MOCK_USERNAME_KEY = "mock_unlogin_user";

    @Override
    public BasicService<Attachment> getBasicService() throws Exception {
        return attachmentService;
    }

    @Override
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> insert(Attachment entity, HttpSession session, HttpServletRequest request,
                                      HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            // 若row_id为空，则后端生成id，并赋值
            if (null == entity.getId()) {
                entity.setId(keyGenerateService.keyGenerate());
            }
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile myfile = multipartRequest.getFile("uploadAttachment");
            Attachment newEntry = attachmentService.insert(myfile, entity);
            result.put("success", true);
            result.put("newRow", newEntry);
            result.put("entity", entity);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 无登录情况下上传附件
     *
     * @author 路江
     * @date 2019-12-24
     * @param entity 附件信息
     * @param session 会话
     * @param request request
     * @param response response
     * @return
     */
    @RequestMapping(value = "/insertAttachment", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> insertAttachment(Attachment entity, HttpSession session, HttpServletRequest request,
                                                 HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile myfile = multipartRequest.getFile("uploadAttachment");
        try {
            Attachment newEntry = attachmentService.insertAttachment(myfile, entity);
            result.put("success", true);
            result.put("newRow", newEntry);
            result.put("entity", entity);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 多附件上传
     *
     * @param entity   附件entity
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/insertWithFiles", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> createAttachments(Attachment entity, HttpSession session, HttpServletRequest request,
                                                 HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        List<MultipartFile> myfiles = multipartRequest.getFiles("uploadAttachment");
        try {
            List<Attachment> rets = new ArrayList<>();
            for (MultipartFile file : myfiles) {
                entity.setId(keyGenerateService.keyGenerate());
                rets.add(attachmentService.insert(file, entity));
            }
            result.put("newRow", rets.size() == 1 ? rets.get(0) : rets);
            result.put("entity", rets.size() == 1 ? rets.get(0) : rets);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 查询资料库列表
     */
    @RequestMapping(value = "/queryLibrary")
    @ResponseBody
    public Map<String, Object> queryLibrary(@JsonParam QueryParams qps, @JsonParam Attachment entity, HttpSession session,
                                            HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            Attachment t = (Attachment) BasicModel.transformClass(Attachment.class, qps);
            List<Attachment> list = attachmentService.queryAttachmentLibraryListPage(t);
            result.put("success", true);
            result.put("rows", list);
            result.put("total", getCount(t, list.size()));
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("rows", new ArrayList<Attachment>());
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 下载路径
     * @param qps
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/downloadPath", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> downloadPath(@JsonParam QueryParams qps, HttpSession session, HttpServletRequest request,
                                            HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            if (null == qps.getId()) {
                throw new ServiceException("PUBLIC-007");
            }
            Attachment entity = new Attachment();
            entity.setId(qps.getId());
            List<Attachment> list = attachmentService.queryByExamplePage(entity);
            if (list.size() != 1) {
                throw new ServiceException("PUBLIC-014");
            }
            Attachment attachment = list.get(0);
            String fileUrl = YmlConstants.getPortalShareUrlDir() + attachment.getAttachmentPath() + "/"
                    + attachment.getAttachmentName();
            result.put("url", fileUrl);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    @Override
    public void beforQueryAllOrExample(Attachment entity, HttpServletRequest request) throws Exception {
        String  headId = "headId";
        if (null == entity.getHeadId()) {
            if (null != entity.getId()) {
                entity.setHeadId(entity.getId());
                // 将ID置空
                entity.setId(0L);
            } else if (StringUtils.isNotBlank(request.getParameter(headId))) {
                entity.setHeadId(Long.parseLong(request.getParameter("headId")));
            } else {
                entity.setHeadId(0L);
            }
        }
    }

    /**
     * <p>
     * 批量下载文件
     * </p>
     *@author yrf
     * @param ids
     * @return
     */
    @RequestMapping(value = "/downloadBatch")
    @ResponseBody
    public Map<String, Object> downloadBatch(String ids) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            if (StringUtils.isBlank(ids)) {
                result.put("success", false);
                result.put("result", "请选中需要下载的文件");
            }
            String[] id = ids.split(",");
            String fileUrl = attachmentService.batchDownload(id);
            result.put("success", true);
            result.put("url", fileUrl);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * @author wangdawei
     * @param attachmentList
     * @return
     */
    @RequestMapping(value = "/batchDelete")
    @ResponseBody
    public Map<String, Object> batchDelete(@RequestBody List<Attachment> attachmentList) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            result = attachmentService.batchDeleteAttch(attachmentList);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("result", e.getMessage());
        }
        return result;
    }

    /**
     * 根据filtersRaw查询附件
     *
     * @author LiYang
     * @date 20191209
     */
    @RequestMapping(value = "/queryByFilterPage")
    @ResponseBody
    public Map<String, Object> queryByFilterPage(@JsonParam QueryParams qps, @JsonParam Attachment entity, HttpSession session,
                                                  HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>(8);
        try {
            qps.preDealSecurity(request);
            Attachment attachment = BasicModel.transformClass(entity, qps);
            //如果filteraRaw条件和headId都为null，则将headId置为0，防止查出所有附件
            if ((null == attachment.getQps().getFilters() || attachment.getQps().getFilters().size() == 0)
                    && null == attachment.getHeadId()) {
                attachment.setHeadId(-1L);
            }
            List<Attachment> list = attachmentService.queryByFilterPage(attachment);
            result.put("success", true);
            result.put("rows", list);
            this.pushCurrentDataCache(list, session.getId(), "base", false);
            result.put("total", getCount(attachment, list.size()));
            result.put("code", ReturnCodeConstants.SUCCESS);
        } catch (BasicServiceException e) {
            LCLogger.withException(e.getDetailMessage());
            result.put("success", false);
            result.put("rows", new ArrayList<Attachment>());
            result.put("result", e.getMessage());
            result.put("detailMessage", e.getDetailMessage());
            result.put("code", e.getCode());
        } catch (Exception e) {
            LCLogger.withException(e.getMessage());
            result.put("success", false);
            result.put("rows", new ArrayList<Attachment>());
            result.put("result", e.getMessage());
            result.put("code", ReturnCodeConstants.EXCEPTION);
        }
        return result;
    }

    /**
     * queryByFilterPage对应的导出功能
     *
     * @author LiYang
     * @date 20191209
     */
    @RequestMapping(value = "/queryByFilterPage/exportData")
    @ResponseBody
    public Map<String, Object> exportFilterData(@JsonParam Attachment entity, @JsonParam QueryParams qps, HttpSession session,
                                          HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>(4);
        try {
            qps.preDealSecurity(request);
            //添加逻辑，判断用户企业帐套的通用导出类型
            CoreUser user = UserUtil.getUser();
            if (null != user) {
                user.setExportType(qps.getExportFileType());
            }
            ExportWriter exportWriter;
            if ("xlsx".equals(user.getExportType())) {
                exportWriter = ExportFactory.newExcelInstance(qps);
            } else {
                exportWriter = ExportFactory.newInstance(qps);
            }
            Attachment attachment = BasicModel.transformClass(entity, qps);
            //如果filteraRaw条件和headId都为null，则将headId置为0，防止查出所有附件
            if ((null == attachment.getQps().getFilters() || attachment.getQps().getFilters().size() == 0)
                    && null == attachment.getHeadId()) {
                attachment.setHeadId(-1L);
            }
            while (!qps.getStopExport()) {
                List<Attachment> list = getBasicService().queryByExamplePage(attachment);
                if (qps.getPage() == 1) {
                    qps.setTotal(attachment.getTotal());
                }
                exportWriter.wirteData(list);
                if ("Y".equals(qps.getExportCurrentPage())) {
                    break;
                }
                attachment.setPage(qps.getPage());
                attachment.setTotalFlag(qps.getTotalFlag());
            }
            result.put("success", true);
            result.put("url", exportWriter.getUrlPath());
            result.put("code", ReturnCodeConstants.SUCCESS);
        } catch (BasicServiceException e) {
            LCLogger.withException(e.getMessage());
            result.put("success", false);
            result.put("result", e.getMessage());
            result.put("detailMessage", e.getDetailMessage());
            result.put("code", e.getCode());
        } catch (Exception e) {
            LCLogger.withException(e.getMessage());
            result.put("success", false);
            result.put("result", e.getMessage());
            result.put("code", ReturnCodeConstants.EXCEPTION);
        }
        return result;
    }

    /**
     * h5附件上传接口
     * @author 姚江漪
     * @date 2019/08/16 16:51
     */
    @RequestMapping(value = "/insertFiles", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> insertFiles(@RequestBody Attachment record, HttpSession session, HttpServletRequest request,
                                           HttpServletResponse response) {
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            // 已经没有内部登陆接口，注释调用语句
            if (UserUtil.getUser() == null) {
                //如果用户信息为空，说明是h5传入，设置临时用户模仿登录
                String mockUserName = RedisUtil.getCommonProperty(MOCK_USERNAME_KEY);
                TokenUtils.setLogin(mockUserName);
            }
            String url = record.getAttachmentPath();
            record.setAttachmentPath("");
            UploadImgInfo ui = ImageUtil.UploadImage(url, record.getModuleType());
            record.setAttachmentPath(ui.getFilePath());
            record.setAttachmentSize(ui.getFileSize());
            record.setAttachmentName(ui.getFileName());
            record.setAttachmentType("jpg");
            record.setId(keyGenerateService.keyGenerate());
            attachmentService.insert(record);
            record = attachmentService.queryById(record);

            result.put("success", true);
            result.put("result", record);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

    /**
     * COS - 获取临时秘钥
     *
     * @author 李莹
     * @date 2020/07/01 04:34
     */
    @PostMapping(value = "/getTmpSecret", name = "获取临时秘钥")
    @ResponseBody
    public Map<String, Object> getTmpSecret(@JsonParam Attachment attachment, HttpSession session,
                                            HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>(8);

        try {
            result = attachmentService.getTmpSecret(attachment);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }

    /**
     * COS - 获取对象预签名URL
     *
     * @author 李莹
     * @date 2020/07/03 05:17
     */
    @PostMapping(value = "/getSingleAttachmentUrl", name = "获取预签名URL")
    @ResponseBody
    public Map<String, Object> getSingleAttachmentUrl(@JsonParam Attachment attachment, HttpSession session,
                                                      HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>(8);
        try {
            result = attachmentService.getSingleAttachmentUrl(attachment);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

    /**
     * COS - 更新link数据
     *
     * @author 李莹
     * @date 2020/07/10 10:54
     */
    @PostMapping(value = "/cosInsert", name = "cos更新link数据")
    @ResponseBody
    public Map<String, Object> cosInsert(@JsonParam Attachment attachment, HttpSession session,
                                         HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>(8);
        try {
            // 调用该接口，默认uploadType为cos
            if (StringUtils.isBlank(attachment.getUploadType())) {
                attachment.setUploadType("cos");
            }
            if (null == attachment.getId()) {
                attachment.setId(keyGenerateService.keyGenerate());
            }
            attachmentService.insert(attachment);
            Attachment newEntry = attachmentService.queryById(attachment);
            result.put("newRow", newEntry);
            result.put("entity", attachment);
            result.put("success", true);
        } catch (Exception e) {
            LCLogger.withException(e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }

        return result;
    }

}
